package com.bluegalaxy.nhb.sql;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bluegalaxy.nhb.util.StringUtil;
import com.bluegalaxy.nhb.core.XxSqlQueryJoin;
import com.bluegalaxy.nhb.domain.constant.SqlKeyConst;
import com.bluegalaxy.nhb.domain.constant.XxBuildConst;
import com.bluegalaxy.nhb.domain.enums.SqlOperEnum;
//import lombok.extern.slf4j.Slf4j;


import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

//@Slf4j
public class AssembleSql {


    private static final String userAttributes = "userAttributes";  //用户属性
    private static final String userActions = "userActions";  //用户行为满足
    private static final String userActionOrders = "userActionOrders";  //行为序列

    /*********************用户画像各条件参数KEY***********************************************/
    private static String type = "type";
    private static String global_relation_key = "globalStr";  //key and/or
    private static String attribute_relation_key = "attributeStr";  //key and/or
    private static String action_relation_key = "actionStr";  //key and/or
    private static String order_relation_key = "orderStr";  //key and/or
    private static String and_value = "且";
    private static String or_value = "或";
    //用户属性
    private static String field_key = "attributeName";
    private static String function_key = "valueExpression";
    private static String params_key = "value1Str";
    private static String params2_key = "value2Str";
    //用户行为满足/行为序列
    private static String dataRange = "dataRange";

    private static String doThings = "doThings";
    private static String eventType = "eventType";

    private static String children = "eventItems";
    private static String e_eventItem = "eventItem";

    private static String e_field_key = "eventType";
    private static String e_function_key = "eventItemExpression";
    private static String e_params_key = "value1Str";
    private static String e_params2_key = "value2Str";

    private static String s_f_time = "time"; //ck sql字段，sql_filed_time
    private static String s_f_enent = "event"; //ck sql字段

    private static String table_events = "events"; //ck events表
    private static String table_users = "users"; //ck users表
    private static String events_alias = "e"; //ck users表
    private static String users_alias = "u"; //ck users表

    private static String relation_id = "e.login_id = u.login_id"; //关联id字段

    private static String distinct_id = "distinct_id";



    public static List<String> getItemField(JSONArray itemArray){
        List<String> fields = new ArrayList<>();
        for (int i = 0;i<itemArray.size();i++){
            JSONObject item = itemArray.getJSONObject(i);
            JSONObject eventItem = item.getJSONObject(e_eventItem);
            String filed = eventItem.getString("eventItemCode");
            fields.add(filed);
        }

        return fields;
    }

    /**
     * 将字符串的首字母转大写
     * @param str 需要转换的字符串
     * @return
     */
    public static String capture(String str) {
        // 进行字母的ascii编码前移，效率要高于截取字符串进行转换的操作
        char[] cs=str.toCharArray();
        cs[0]-=32;
        return String.valueOf(cs);
    }

    public static void assemle(String filed,String function,Object params,XxSqlQueryJoin xxSql){
        if (StringUtil.isEmpty(filed) || params == null
                || StringUtil.isEmpty(function)){
            return;
        }
        switch (function){
            case XxBuildConst.EQUAL:
                xxSql.equal(filed,params);
                break;
            case XxBuildConst.AND_EQUAL:
                xxSql.andEqual(filed,params);
                break;
            case XxBuildConst.OR_EQUAL:
                xxSql.orEqual(filed,params);
                break;

            case XxBuildConst.NOT_EQUAL:
                xxSql.notEqual(filed,params);
                break;
            case XxBuildConst.AND_NOT_EQUAL:
                xxSql.andNotEqual(filed,params);
                break;
            case XxBuildConst.OR_NOT_EQUAL:
                xxSql.orNotEqual(filed,params);
                break;

            case XxBuildConst.MORE:
                xxSql.moreThan(filed,params);
                break;
            case XxBuildConst.AND_MORE:
                xxSql.andMoreThan(filed,params);
                break;
            case XxBuildConst.OR_MORE:
                xxSql.orMoreThan(filed,params);
                break;

            case XxBuildConst.LESS:
                xxSql.lessThan(filed,params);
                break;
            case XxBuildConst.AND_LESS:
                xxSql.andLessThan(filed,params);
                break;
            case XxBuildConst.OR_LESS:
                xxSql.orLessThan(filed,params);
                break;

            case XxBuildConst.MORE_EQUAL:
                xxSql.moreEqual(filed,params);
                break;
            case XxBuildConst.AND_MORE_EQUAL:
                xxSql.andMoreEqual(filed,params);
                break;
            case XxBuildConst.OR_MORE_EQUAL:
                xxSql.orMoreEqual(filed,params);
                break;

            case XxBuildConst.LESS_EQUAL:
                xxSql.lessEqual(filed,params);
                break;
            case XxBuildConst.AND_LESS_EQUAL:
                xxSql.andLessEqual(filed,params);
                break;
            case XxBuildConst.OR_LESS_EQUAL:
                xxSql.orLessEqual(filed,params);
                break;

            case XxBuildConst.LIKE:
                xxSql.like(filed,params);
                break;
            case XxBuildConst.AND_LIKE:
                xxSql.andLike(filed,params);
                break;
            case XxBuildConst.OR_LIKE:
                xxSql.orLike(filed,params);
                break;

            case XxBuildConst.NOT_LIKE:
                xxSql.notLike(filed,params);
                break;
            case XxBuildConst.AND_NOT_LIKE:
                xxSql.andNotLike(filed,params);
                break;
            case XxBuildConst.OR_NOT_LIKE:
                xxSql.orNotLike(filed,params);
                break;

            case XxBuildConst.IS_NULL:
                xxSql.isNull(filed);
                break;
            case XxBuildConst.AND_IS_NULL:
                xxSql.andIsNull(filed);
                break;
            case XxBuildConst.OR_IS_NULL:
                xxSql.orIsNull(filed);
                break;

            case XxBuildConst.IS_NOT_NULL:
                xxSql.isNotNull(filed);
                break;
            case XxBuildConst.AND_IS_NOT_NULL:
                xxSql.andIsNotNull(filed);
                break;
            case XxBuildConst.OR_IS_NOT_NULL:
                xxSql.orIsNotNull(filed);
                break;

            case XxBuildConst.TRUE:
                xxSql.andEqual(filed,XxBuildConst.TRUE);
                break;
            case XxBuildConst.AND_TRUE:
                xxSql.andIn(filed,new String[]{XxBuildConst.U_TRUE,XxBuildConst.TRUE,"1"});
                break;
            case XxBuildConst.OR_TRUE:
                xxSql.orIn(filed,new String[]{XxBuildConst.U_TRUE,XxBuildConst.TRUE,"1"});
                break;
            case XxBuildConst.FALSE:
                xxSql.andEqual(filed,XxBuildConst.FALSE);
                break;
            case XxBuildConst.AND_FALSE:
                xxSql.andIn(filed,new String[]{XxBuildConst.U_FALSE,XxBuildConst.FALSE,"0"});
                break;
            case XxBuildConst.OR_FALSE:
                xxSql.andIn(filed,new String[]{XxBuildConst.U_FALSE,XxBuildConst.FALSE,"0"});
                break;
            default:
                return;
        }
    }

    public static void assemleBetween(String filed,String function,Object startParam,Object endParam,XxSqlQueryJoin xxSql){
        if (StringUtil.isEmpty(filed)
                || StringUtil.isEmpty(function)){
            return;
        }
        switch (function){
            case XxBuildConst.BETWEEN:
                xxSql.between(filed,startParam,endParam);
                break;
            case XxBuildConst.AND_BETWEEN:
                xxSql.andBetween(filed,startParam,endParam);
                break;
            case XxBuildConst.OR_BETWEEN:
                xxSql.orBetween(filed,startParam,endParam);
                break;

            default:
                return;
        }
    }

    public static void assemleIn(String filed, String function, Object value, XxSqlQueryJoin xxSql){
        if (StringUtil.isEmpty(filed)
                || StringUtil.isEmpty(function)){
            return;
        }
        Object[] tmpValues=null;
        if(value instanceof Array){
            tmpValues=(Object[])value;
        }
        if(value instanceof Object[]){
            tmpValues=(Object[])value;
        }
        if(value instanceof Collection){
            tmpValues=((Collection<?>)value).toArray();
        }
        if(value instanceof String){
            tmpValues = new Object[1];
            tmpValues[0]=value;;
        }
        switch (function){
            case XxBuildConst.IN:
                xxSql.in(filed,tmpValues);
                break;
            case XxBuildConst.AND_IN:
                xxSql.andIn(filed,tmpValues);
                break;
            case XxBuildConst.OR_IN:
                xxSql.orIn(filed,tmpValues);
                break;
            case XxBuildConst.NOT_IN:
                xxSql.notIn(filed,tmpValues);
                break;
            case XxBuildConst.AND_NOT_IN:
                xxSql.andNotIn(filed,tmpValues);
                break;
            case XxBuildConst.OR_NOT_IN:
                xxSql.orNotIn(filed,tmpValues);
                break;

            default:
                return;
        }
    }
}
